module Hexena.Cmds.BloomGenerate (run) where

import Data.Binary.Put
import Data.IFF
import System.IO (hPutStrLn, stderr)
import Text.Printf
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL

import Hexena.Internal.Blooming

saveBloomFilter :: Int -> Blooming B.ByteString -> IO ()
saveBloomFilter n = B.putStr . toByteString . save . saveBLOM
    where chunkNGRM = Cons (chunkIdFromString "NGRM") $ Chunk $ B.concat $ BL.toChunks $ runPut (putWord16be (fromIntegral n))
          save :: T -> T
          save x = if n > 65535 then
                       error "n-grams too large"
                   else
                       x { chunk = Form $ chunkNGRM : parts (chunk x) }

-- | Generate bloom filter data
--
run :: [String] -- ^ List of Filenames
    -> Int      -- ^ Which kind of n-grams, 2-grams, 3-grams, etc.
    -> Int      -- ^ specify the maximum number of bits in filter
    -> IO ()
run args ngrams modulo = do
  bf <- fillBloomFromFileIO ngrams (fromIntegral modulo) args
  filledBits <- bloomingQueryFillM bf
  let mymodul = bloomingModuloM bf
  let ratio = fromIntegral filledBits / fromIntegral mymodul :: Double
  hPutStrLn stderr $ printf "filledBits = $%06X, ratio = %e" filledBits ratio
  bloomingFreezeM bf >>= saveBloomFilter ngrams
